Skip to main content

Using the plugin

πŸ“Œ Using the pytest-bdd-ewx Plugin​

This plugin is heavily based on the PyTest BDD plugin. As such, users are expected to leverage the Cucumber framework to write their tests. For a deeper understanding of these two tools please refer to their respective documentations.

In short though, users should write their tests in .feature files using the Gherkin syntax and then add Python functions that add functionality to the steps described in the Gherkin scenarios. These Python functions are linked to the Gherkin steps using Python decorators provided by pytest-bdd.

The Pytest BDD Energyworx plugin provides a number of steps out of the box. In many cases these should be enough to write complete test scenarios. This means users only have to write the .feature files and the plugin will take care of the actual logic. This does mean that the wording of the Cucumber steps needs to be the same as the steps defined in the plugin.

Custom steps can also be created. To make it easier, the plugin provides a number of PyTest fixtures which can be requested/injected into the Python functions for these custom steps.

πŸš€ Feature files​

A feature file can consist of multiple scenarios the tester wants to test, written in the Gherkin syntax.

Feature​

First, the creator of a feature file explains what the feature file is for, in a Who, What, Why fashion: as a(n) … I want to … So that I / In order to …, like this:

Feature: Explaining feature file
As a non-programmer
I want to have an overview of Cucumber that is understandable by non-developers
In order to gain an understanding of the Cucumber testing system

N.B.: Keep your feature readable by making use of indentation. Please also note that this does not trigger any test. It’s merely a description.

Scenario​

Scenarios are built up from step definitions. A step definition starts either with the keywords Given, When and Then. Typically, keywords occur in that order.

Simple example:

Scenario: Cucumber test
Given I have "5" cucumbers
When I eat "2" cucumbers
Then I should have "3" cucumbers

Syntax​

The above example states scenario which consist of step definitions. The step definitions have to be syntactically the same as the plugin step definitions. Failure to comply with this syntax will mean PyTest BDD will not be able to link the test scenarios to their logical implementation in Python.

The values in quotation marks are usually a step parameters which are treated as a variable in the step implementation, which allows to reuse the same step multiple times in different scenarios to set up or verify various values.

πŸ› οΈ Types of fixtures​

The PyTest BDD Energyworx plugin provides a number of different types of fixtures. They generally fall under one of the categories described below. Some fixtures provide a combination of categories. For instance, steps can also be used as helper functions.

Shared state​

Fixtures that provide shared state are used to carry over data from one test to another. The state, and any mutations on it, are propagated down chain. Meaning if a fixture before the current one modified the state, that modification will be present in the state the current fixture receives.

Examples are the context fixture which allows for storing arbitrary meta data and share this between tests.

Clients​

Clients are tools for interacting with the API of a certain domain entity. They abstract away the logic needed for API communication and can be injected into tests when direct communication with an API is needed.

An example is the datasource_client for interacting with the datasource API.

Helper functions​

Helper functions are fixtures that make common logic reusable. Any test that needs to use the logic they describe can request to have them injected.

Steps​

Steps are a special type of fixture provided by the pytest-bdd library. They describe a step in the BDD scenario under test. Since many of the test scenarios will share similar steps, mainly setup and teardown logic, a number of commonly used steps is provided for you by the plugin.

An example is the step to create a new data source:

@given(parsers.parse('I create all datasources from "{file_name}"'))
def create_datasources(
...

You can reuse this step that is provided for you by the plugin by simply adding a line like the following to your .feature file:

Given I create all datasources from "my_datasource_file.json"

For more information about available steps in the plugin, please refer to Available Gherkin Steps documentation.

πŸ“‚ List of fixtures​

The different fixtures that are available to you can be explored through the Pytest documentation. In general, they are placed in a package under pytest_bdd_ewx, using the name of said entity. Within those packages you may find the following files.

client.py​

Herein the client, for interacting with the API endpoints corresponding to a specific entity, is defined. The fixture that makes this client available can be found in fixtures.py.

fixtures.py​

A file wherein all fixtures which are not steps are defined for the specific entity.

steps.py​

Here all reusable steps for the specific entity are defined.

Generic steps​

There are some generic fixtures that can be used for any entity by specifying the object type in the step definition. Those steps are located in objects.py file under the pytest_bdd_ewx package itself. For example:

@then(parsers.parse('the "{obj_type_name}" with the name "{obj_name}" exists'))
def check_object_exists_by_name(
...

This step can be reused in .feature file in this way:

Then the "trigger" with the name "My_trigger" exists

Restrictions on specific steps​

If you want to update several fields of an object by PUT request using configuration file, you can use the step:

When I update the "{obj_type_name}" with the name "{name}" with configuration file "{file_name}"

and verify it was properly updated by the step:

Then I get the "{obj_type_name}" by id and verify all updated fields

When using this step, we need to be sure that we expect to get exactly the same object as we sent in update request.

πŸ“œ Providing Test Data​

πŸ“¦ Uploading configurations​

For seamless configuration management, we recommend utilising ewx-cli energyworx tool which helps with both downloading and uploading the needed configurations for the specific test case. For more information about this tool, please reach out to support team.

Once you install ewx-cli package, you can easily start using it from the command line, check existing capabilities with the command:

ewx-cli --help

Perhaps the most common command that you will need for testing purposes is downloading the needed configurations to your test folder for the test preconditions, for instance:

ewx-cli config download --market-adapter <id> <target-project/namespace> my_test_scenarios/configs

where the latter is your preferred folder to keep those configurations. This command will download not only the market adapter config, but also all its dependencies like transformation configuration, and related channel classifiers, flows etc. Note that market-adapter in this example is the desired config, it can be any other resource, please see ewx-cli help.

If the operation was successful, you will see the folder appearing by the path specified in the command:

|-  my-test-project
|- my_test_scenarios
|- configs
|- features

After it's done, simply use the following 2 steps as a preconditions to your scenarios:

Given I create a resource manager with name "my_test_resource_manager" from directory "my_test_scenarios/configs"
And I upload all configurations using the resource manager with name "my_test_resource_manager"

With these steps executed, the configurations will be uploaded (or updated if already exist on the target namespace) to the platform, and you can continue testing.

πŸ’Ύ Test data management​

Certain fixtures will require you to provide the data for them in file form. For instance, the datasource creation step:

Given I create all datasources from "test_datasources.json"

expects a file under resources/test-data/datasources/test_datasources.json. To adhere to this requirement that data folder will need to be present under the resource folder located in the root of the test folder of your project.

Same applies to file uploading to the file management:

Given I upload the file "test_data.csv"

expects a file under resources/test-data/file/test_data.csv.

This is also applicable to some of more advanced steps that utilise json payloads for updating the resources. Appropriate resource folder will need to be created depending on the entity type used in the test step.